package uebung04_h;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import tools.ColorConversions;
import tools.Gauss;
import tools.Image;
import tools.ShowImage;
import tools.Tester01;
import tools.Tester02;

public class Harris01 {
	public static double[] dx(double[] input, int w, int h, double[] output) {
		for (int i = 0; i<input.length; i++) {
			int x = i%w, y = i/w;
			int index = (x+w+1)%w+y*w;
			output[i] = -(input[i]-input[index]);
		}
		return output;
	}
	
	public static double[] dy(double[] input, int w, int h, double[] output) {
		for (int i = 0; i<input.length; i++) {
			int x = i%w, y = i/w;
			int index = x+((y+1+h)%h)*w;
			output[i] = input[i]-input[index];
		}
		return output;
	}
	public static int[] prepare(double[] input, int[] fillme) {
		double max = Double.NEGATIVE_INFINITY, min = Double.POSITIVE_INFINITY;
		for (int i = 0; i<input.length; i++) {
			max = Math.max(input[i], max);
			min = Math.min(input[i], min);
		}
		double span = max-min;
		for (int i = 0; i<input.length; i++) {
			fillme[i] = (int)(255.*((input[i]-min)/span));
		}
		return fillme;
	}
	public static int[] fuseRGB(int[] r, int[] g, int[] b, int[] fillme) {
		for (int i = 0; i<fillme.length; i++) {
			fillme[i] = r[i]<<16 | g[i]<<8 | b[i] | 0xFF000000;
		}
		return fillme;
	}

	public static void main(String[] args) {
		try {
			BufferedImage bi = ImageIO.read(Harris01.class.getClassLoader().getResourceAsStream("res/test2.png"));
			final int w = bi.getWidth(), h = bi.getHeight();
			int[] pixels = bi.getRGB(0, 0, w, h, new int[w*h], 0, w);
			
			int[] lum = ColorConversions.getFastLuminance(pixels, new int[w*h]);
			double[] lumd = Image.getScalarLuminance(lum, new double[w*h]);
			
			final double[] dx = dx(lumd, w, h, new double[w*h]);
			final double[] dy = dy(lumd, w, h, new double[w*h]);
			
			final int neighbours = 4;
			final double[] Rs = new double[w*h];
			final double k = 0.025, sigma = neighbours/3.;
			
			System.out.println(sigma);
			
			for (int y = 0; y<h; y++) {
				for (int x = 0; x<w; x++) {
					
					double sum = 0, xx = 0, yx = 0, yy = 0;
					
					for (int j = -neighbours; j<neighbours; j++) {
						for (int i = -neighbours; i<neighbours; i++) {
							
							int index = ((x+i+w)%w)+((y+j+h)%h)*w;
							
							double dx_ = dx[index], dy_ = dy[index], weight = Math.exp(-Math.sqrt(i*i+j*j)/(2*sigma*sigma));
							
							xx += dx_*dx_*weight;
							yx += dy_*dx_*weight;
							yy += dy_*dy_*weight;
							
							sum += weight;
						}
					}
					System.out.println(sum);
					xx /= sum;
					yx /= sum;
					yy /= sum;
					
					Rs[x+y*w] = (xx*yy-yx*yx)-k*(xx+yy)*(xx+yy); 
				}
			}
			
			double max = Double.NEGATIVE_INFINITY, min = Double.POSITIVE_INFINITY;
			
			for (int i = 0; i<Rs.length; i++) {
				max = Math.max(max, Rs[i]);
				min = Math.min(min, Rs[i]);
			}
			
			System.out.println(max+ " "+ min);
			
			int[] rint = prepare(Rs, new int[w*h]);
			
			int[] rgb = fuseRGB(rint, rint, rint, new int[w*h]);
			bi.setRGB(0, 0, w, h, rgb, 0, w);
			
			JFrame ff = new JFrame();
			ff.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			ff.add(new ShowImage(bi));
			ff.pack();
			ff.setVisible(true);
			
 			
		}
		catch (IOException iox) {
			iox.printStackTrace();
		}
	}
}
